package com.x.Part5_饿汉式单例的线程安全;

/**
 * ClassName: BankTest
 * Package: IntelliJ IDEA
 * Description:懒汉式单例模式
 * Written by HanXu
 * Create 2024.03.27 18:17
 */
public class BankTest {

    static Bank b1 = null;
    static Bank b2 = null;

    public static void main(String[] args) {

        Thread t1 = new Thread(){
            @Override
            public void run() {
                b1 = Bank.getInstance();
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                b2 = Bank.getInstance();
            }
        };

        t1.start();
        t2.start();

        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

            System.out.println(b1);
            System.out.println(b2);
            System.out.println(b1 == b2);

    }
}

class Bank{

    private Bank(){}

    private static volatile Bank instance = null; //实例对象先造好


    //存在线程安全问题,this不唯一
    //public static Bank getInstance(){
    /**
     * 方式一：静态方法的同步监视器为Bank.class,唯一
    public static synchronized Bank getInstance(){
        if(instance == null){
            instance = new Bank();
        }
        return instance;
    }
    */

    /**
    //方式二：使用同步代码块
    public static Bank getInstance(){
        synchronized (Bank.class) {
            if(instance == null)
                instance = new Bank();
            return instance;
        }
    }
    */

    //方式三：优化的同步代码块
    //为了避免指令重排，将instance用volatile修饰
    public static Bank getInstance(){
        if (instance == null) {//再加一层，同步代码块只进去一次
            synchronized (Bank.class) {
                if(instance == null)
                    instance = new Bank();
            }
        }
        return instance;
    }
}